/* eslint-disable @typescript-eslint/ban-types */
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import Map from "ol/Map";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import View from "ol/View";
import Draw, { createBox } from "ol/interaction/Draw";
import WKT from "ol/format/WKT";
import GeoJsonFormat from "ol/format/GeoJson";
import GeoJSON from "ol/format/GeoJSON";
import { bbox } from "ol/loadingstrategy";
import Feature from "ol/Feature";
import { Style, Fill, Stroke, Circle } from "ol/style";
import { defaults as controlDefaults } from "ol/control/defaults";
import { defaults as interactionDefaults } from "ol/interaction/defaults";
import Select from "ol/interaction/Select";
import Modify from "ol/interaction/Modify";
import * as Condition from "ol/events/condition";
import loadMap from "@/utils/maptools/loadMap";
import slicingService from "@/utils/maptools/slicingService";
import Polygon from "ol/geom/Polygon";
import { Collection, Overlay } from "ol";
import LineString from "ol/geom/LineString";
import { getArea, getLength } from "ol/sphere";
import { unByKey } from "ol/Observable";
import { Geometry } from "ol/geom";
import ScaleLine from "ol/control/ScaleLine";
import wfsService from "./wfsService";
import { log } from "console";
import TileLayer from "ol/layer/Tile";
import TileWMS from "ol/source/TileWMS";
// 设置图层样式
const layerStyles = {
	// 矢量图层的默认样式
	default: new Style({
		image: new Circle({
			radius: 6,
			stroke: new Stroke({
				color: "rgb(238, 0, 0)",
				width: 2,
			}),
			fill: new Fill({
				color: "rgba(238, 0, 0, 0.5)",
			}),
		}),
		fill: new Fill({
			color: "rgba(238, 0, 0, 0.5)",
		}),
		stroke: new Stroke({
			color: "rgb(238, 0, 0)",
			width: 3,
		}),
	}),
	// 要素选中样式
	select: new Style({
		image: new Circle({
			radius: 5,
			stroke: new Stroke({
				color: "rgb(0, 153, 255)",
				width: 2,
			}),
			fill: new Fill({
				color: "rgba(255, 255, 255, 0.8)",
			}),
		}),
		fill: new Fill({
			color: "rgba(255, 255, 255, 0.8)",
		}),
		stroke: new Stroke({
			color: "rgb(0, 153, 255)",
			width: 3,
		}),
	}),
};

// 矢量图层列表——可编辑
const vectorLayerList: Record<string, VectorLayer<VectorSource> | null> = {
	"ai-interpretation": null,
	"ai-change-detection-l": null,
	"ai-change-detection-r": null,
};
// 矢量图层列表——不可编辑
const unEditedVecLayerList: Record<string, VectorLayer<VectorSource> | null> = {
	"ai-interpretation": null,
	"ai-change-detection-l": null,
	"ai-change-detection-r": null,
};

// 创建地图实例列表
const mapList: Record<string, Map | null> = {
	"ai-interpretation": null,
	"ai-interpretation1": null,
	"ai-change-detection-l": null,
	"ai-change-detection-r": null,
};

// 测量图层列表
const measureVectorLayerList: Record<string, VectorLayer<VectorSource> | null> = {
	"ai-interpretation": null,
	"ai-change-detection-l": null,
	"ai-change-detection-r": null,
};

/**
 * 地图初始化，天地图基础图层加载和矢量图层加载
 * @param { Array<layerType> } layerList - 获取不同图层需要的参数，如['cia_']
 * @param { sting } target - dom元素的id，如'map'
 * @param {string} mIndex - 地图或矢量源索引
 * @param {{ScaleLine: string}} - 地图控件显示位置
 * @param {Function | undefined} callback - 地图初始化回调函数
 */
const initMap = (
	layerList: any,
	target = "map",
	mIndex = "",
	controlTarget = { scaleLine: "" },
	callback: any = undefined
): Map => {
	// 添加比例尺控件
	const scaleLineControl = new ScaleLine({
		units: "metric",
		target: controlTarget.scaleLine,
	});
	const newMap = new Map({
		// 设置视图
		view: new View({
			center: [100.397128, 30.916527],
			maxZoom: 23,
			minZoom: 1,
			zoom: 5,
			projection: "EPSG:4326",
		}),
		// 关闭地图默认控件
		controls: controlDefaults({
			zoom: false,
			rotate: false,
			attribution: false,
		}).extend([scaleLineControl]),
		// 关闭地图默认交互行为
		interactions: interactionDefaults({
			doubleClickZoom: false,
		}),
	});
	// 获取地图挂载位置
	const mapDom: HTMLElement | null = document.querySelector(`#${target}`);
	if (!mapDom) {
		return newMap;
	}
	// 挂载地图
	newMap.setTarget(mapDom);
	// 加载图层并添加基础图层
	let layerIndex = 1;
	for (const layer of layerList) {
		const mapLayer = loadMap(layer);
		mapLayer.setZIndex(layerIndex++);
		newMap.addLayer(mapLayer);
	}
	const baseLayer = new VectorLayer({
		source: new VectorSource(),
		style: layerStyles.default,
		zIndex: 2023,
	});
	newMap.addLayer(baseLayer);
	const unEditedLayer = new VectorLayer({
		source: new VectorSource(),
		style: layerStyles.default,
		zIndex: 2023.5,
	});
	newMap.addLayer(unEditedLayer);
	const measureLayer = new VectorLayer({
		source: new VectorSource(),
		style: new Style({
			fill: new Fill({
				color: "rgba(255, 255, 255, 0.2)",
			}),
			stroke: new Stroke({
				color: "rgba(255,255,0,1)",
				width: 3,
			}),
		}),
		zIndex: 2024,
	});
	if (measureLayer) {
		// 添加测量图层
		newMap.addLayer(measureLayer);
	}
	if (callback instanceof Function) {
		callback(newMap);
	}
	vectorLayerList[mIndex] = baseLayer;
	unEditedVecLayerList[mIndex] = unEditedLayer;
	measureVectorLayerList[mIndex] = measureLayer;
	mapList[mIndex] = newMap;
	return newMap;
};

// 几何转换为wkt
const geometryToWkt = (geometry: Geometry | undefined) => {
	if (!geometry) {
		return;
	}
	const wktFormat = new WKT();
	const wkt = wktFormat.writeGeometry(geometry);
	return wkt;
};

// feature转wkt
const featureToWkt = (feature: Feature | undefined) => {
	if (!feature) {
		return "";
	}
	const wktFormat = new WKT();
	const wkt = wktFormat.writeFeature(feature);
	return wkt;
};

// feature转GeoJson
const featureToGeoJson = (feature: Feature<Geometry> | undefined) => {
	if (!feature) {
		return;
	}
	const geoJsonFormat = new GeoJsonFormat();
	const geoJson = geoJsonFormat.writeFeatureObject(feature);
	return geoJson;
};

// GeoJson转feature
const geoJsonToFeature = (geoJson: string) => {
	if (!geoJson) {
		return;
	}
	const geoJsonFormat = new GeoJsonFormat();
	const feature = geoJsonFormat.readFeature(geoJson);
	return feature;
};

// 清除图层中要素
const clearVectorLayer = (vecIndex: string) => {
	const source = vectorLayerList[vecIndex]?.getSource();
	console.log(source);

	vectorLayerList[vecIndex]?.getSource()?.clear();
	unEditedVecLayerList[vecIndex]?.getSource()?.clear();
};

// 通过wkt加载要素
const loadFeatureByWkt = (
	mIndex: string,
	wkt: any,
	id: string | number,
	widthEdit = true,
	style: [StrokeColor: string, FillColor: string] = ["rgb(255, 255, 0)", "rgba(255, 255, 0, 0.5)"]
) => {
	let source;
	if (widthEdit) {
		// 可通过添加交互行为编辑的矢量图层
		source = vectorLayerList[mIndex]?.getSource();
	} else {
		// 不可通过添加交互行为编辑的矢量图层
		source = unEditedVecLayerList[mIndex]?.getSource();
	}
	const wktFormat = new WKT();
	const geometry = wktFormat.readGeometry(wkt);
	const feature = new Feature();
	feature.setGeometry(geometry);

	feature.setStyle(
		new Style({
			image: new Circle({
				radius: 6,
				stroke: new Stroke({
					color: style[0],
					width: 2,
				}),
				fill: new Fill({
					color: style[1],
				}),
			}),
			fill: new Fill({
				color: style[1],
			}),
			stroke: new Stroke({
				color: style[0],
				width: 3,
			}),
		})
	);
	if (id) {
		feature.setId(id);
	}
	source?.addFeature(feature);
};
const addjsonFeature = (mIndex: string, geojsonstring: any) => {
	// // 调整视图以适应新添加的要素
	const geojson = JSON.parse(geojsonstring);
	const view = mapList[mIndex]?.getView();
	console.log(geojson);

	// 创建一个矢量数据源

	const source = vectorLayerList[mIndex]?.getSource();

	// 创建矢量图层并设置样式
	const vectorLayer = new VectorLayer({
		source: source,
		style: new Style({
			image: new Circle({
				radius: 5,
				fill: new Fill({ color: "red" }),
				stroke: new Stroke({ color: "black", width: 1 }),
			}),
			fill: new Fill({
				color: "rgba(255, 0, 0, 0.2)",
			}),
			stroke: new Stroke({
				color: "red",
				width: 2,
			}),
		}),
	});

	// 将图层添加到地图中

	// 解析并添加 Feature 到矢量图层
	const format = new GeoJSON();
	geojson.features.forEach((featureData) => {
		const feature = new Feature();
		const geometry = format.readGeometry(featureData.geometry);

		feature.setGeometry(geometry);
		console.log(feature, "feature");

		source.addFeature(feature);
	});
	mapList[mIndex]?.addLayer(vectorLayer);

	// 定位到包含所有 Feature 的视图
	const extent = source.getExtent(); // 获取所有特征的扩展范围
	console.log(extent);

	view?.fit(extent, { duration: 1000 }); // 设置视图适应这个范围并加上动画
};
//根据id删除图层
const removeFeatureById = (mIndex: string, id: string | number, widthEdit = false) => {
	let source;
	if (widthEdit) {
		// 可编辑的矢量图层
		source = vectorLayerList[mIndex]?.getSource();
	} else {
		// 不可编辑的矢量图层
		source = unEditedVecLayerList[mIndex]?.getSource();
	}

	if (!source) {
		console.warn("图层源不存在");
		return;
	}

	const featureToRemove = source.getFeatureById(id);
	console.log(vectorLayerList[mIndex]);
	console.log(source.getFeatures());

	console.log(source.getFeatureById(id));

	if (featureToRemove) {
		source.removeFeature(featureToRemove);
		console.log(`Feature with id ${id} has been removed`);
	} else {
		console.warn(`未找到 id 为 ${id} 的 feature`);
	}
};

// 矢量图层添加要素
const addFeatureToVector = ({
	mIndex,
	list,
	dataType,
	fillColor,
	strokeColor,
}: Record<any, any>) => {
	const source = vectorLayerList[mIndex]?.getSource();
	switch (dataType) {
		case "geometry": {
			list.forEach((geometry: Geometry) => {
				const feature = new Feature();
				feature.setGeometry(geometry);
				feature.setStyle(
					new Style({
						stroke: new Stroke({
							width: 2,
							color: strokeColor,
						}),
						fill: new Fill({
							color: fillColor,
						}),
					})
				);
				source?.addFeature(feature);
			});
			break;
		}
		case "feature": {
			list.forEach((feature: Feature) => {
				feature.setStyle(
					new Style({
						stroke: new Stroke({
							width: 2,
							color: strokeColor,
						}),
						fill: new Fill({
							color: fillColor,
						}),
					})
				);
				source?.addFeature(feature);
			});
			break;
		}
	}
};

// 根据wkt定位范围
const locationByWkt = (mIndex: string, wkt: string) => {
	const wktFormat = new WKT();
	const geometry = wktFormat.readGeometry(wkt);
	const extent = geometry?.getExtent();
	if (extent === undefined) {
		return;
	}
	const view = mapList[mIndex]?.getView();
	view?.fit(extent, { padding: [200, 200, 200, 200] });
};
const locationByBbox = (mIndex: string, bbox: any) => {
	const arr = JSON.parse(bbox);
	console.log(arr);
	const view = mapList[mIndex]?.getView();
	view?.fit(arr, { padding: [200, 200, 200, 200] });
};
/**--------------------------------Draw交互行为相关--------------------------------------------*/
// 绘制交互
let drawInteraction: Draw | null = null;
/**
 * 添加绘制地图交互行为
 * @param { string } type - 绘制的图形类型
 * @param { Record<string, DrawEvent | undefined>[] } eventList - 绘制监听事件类型和事件监听
 * @param { string } mIndex - 地图或矢量源索引
 */
const addDrawInteraction = (
	mIndex = "",
	type: string,
	eventList: Array<{ eventType: string; event: any }> = []
) => {
	const source = vectorLayerList[mIndex]?.getSource();
	if (source === null) {
		return;
	}
	// 清空矢量图层的所有要素
	// source.clear();
	// 清除交互行为
	removeDrawInteraction(mIndex);
	// 绘制矩形
	if (type === "box") {
		drawInteraction = new Draw({
			source,
			type: "Circle",
			geometryFunction: createBox(),
		});
	}
	// 绘制点和多边行
	if (type === "Point" || type === "Polygon" || type === "LineString") {
		drawInteraction = new Draw({
			source,
			type,
		});
	}
	eventList.forEach((item) => {
		const { eventType, event } = item;
		if (eventType && event) {
			drawInteraction?.addEventListener(eventType, event);
		}
	});
	// 添加交互行为
	drawInteraction !== null && mapList[mIndex]?.addInteraction(drawInteraction);
};

// 移除交互行为
const removeDrawInteraction = (mIndex: string) => {
	if (drawInteraction === null) {
		return;
	}
	// 移除绘制交互行为
	mapList[mIndex]?.removeInteraction(drawInteraction);
	drawInteraction = null;
};

/**--------------------------------Draw交互行为相关--------------------------------------------*/

/**--------------------------------Select交互行为相关--------------------------------------------*/
// 选中交互
let selectInteraction: Select | null = null;

/**
 * 添加选中交互行为
 * @param { string } mIndex - 地图或矢量源索引
 * @param { Record<string, SelectEvent | undefined>[] } eventList - 选中监听事件类型和事件监听
 */
const addSelectInteraction = (
	mIndex = "",
	eventList: Array<{ eventType: string; event: any }> = []
) => {
	// 清除交互行为
	removeSelectInteraction(mIndex);
	selectInteraction = new Select({
		layers: [vectorLayerList[mIndex]],
		condition: Condition.click,
		// toggleCondition: Condition.platformModifierKeyOnly,
		style: layerStyles.select,
	});
	eventList.forEach((item) => {
		const { eventType, event } = item;
		if (eventType && event) {
			selectInteraction?.addEventListener(eventType, event);
		}
	});
	selectInteraction !== null && mapList[mIndex]?.addInteraction(selectInteraction);
};

// 移除选中交互行为
const removeSelectInteraction = (mIndex: string) => {
	if (selectInteraction === null) {
		return;
	}
	mapList[mIndex]?.removeInteraction(selectInteraction);
	selectInteraction = null;
};

// 切换要素选中状态
const changeFeatureStatus = (feature: Feature<Geometry>) => {
	if (selectInteraction) {
		selectInteraction.getFeatures().clear();
		selectInteraction.getFeatures().push(feature);
	}
};

/**--------------------------------Select交互行为相关--------------------------------------------*/

/**--------------------------------Modify交互行为相关--------------------------------------------*/
// 要素编辑行为
let modifyInteraction: Modify | null = null;
/**
 * 添加要素编辑行为
 * @param mIndex - 地图索引
 * @param eventList - 监听事件列表
 * @param features - 限制编辑的矢量
 */
const addModifyInteraction = (
	mIndex: string,
	eventList: Array<{ eventType: string; event: any }> = [],
	features: Feature<Geometry>[] | undefined = undefined
) => {
	const source = vectorLayerList[mIndex]?.getSource();
	if (source === null) {
		return;
	}
	// 清除交互行为
	removeModifyInteraction(mIndex);
	modifyInteraction = new Modify({
		source,
		features: features && new Collection(features),
	});
	eventList.forEach((item) => {
		const { eventType, event } = item;
		if (eventType && event) {
			modifyInteraction?.addEventListener(eventType, event);
		}
	});
	modifyInteraction !== null && mapList[mIndex]?.addInteraction(modifyInteraction);
};

// 移除要素编辑行为
const removeModifyInteraction = (mIndex: string) => {
	if (modifyInteraction === null) {
		return;
	}
	mapList[mIndex]?.removeInteraction(modifyInteraction);
	modifyInteraction = null;
};
/**--------------------------------Modify交互行为相关--------------------------------------------*/

/**--------------------------------切片图层相关--------------------------------------------*/

// 存储切片图层
const slicingLayerList: Record<string, any> = {};

// 调切片服务，添加图层
const addSlicingLayer = (mIndex: string, filePath: string) => {
	console.log(mIndex, filePath, "addSlicingLayer");

	const layer = slicingService.getWMSLayer(filePath);
	layer.setZIndex(2022);
	slicingLayerList[filePath] = layer;
	mapList[mIndex]?.addLayer(layer);
};
const addSlicingWFSLayer = (mIndex: string, filePath: string, layername: string) => {
	const baseUrl = BASE_CONFIG.sliceService;
	const source = new TileWMS({
		url: filePath, // WMS 服务的 URL
		params: {
			LAYERS: layername,
			TILED: true,
			FORMAT: "image/png",
		},
		serverType: "geoserver",
	});

	// 创建图层
	const layer = new TileLayer({
		source: source,
		zIndex: 2022, // 设置图层的层级
	});

	slicingLayerList[layername] = layer;
	mapList[mIndex]?.addLayer(layer);
	console.log(slicingLayerList, layername, "addslicingLayerList");
};
const slicingLayerList1: Record<string, any> = {};
const slicingLayerList2: Record<string, any> = {};

const addSlicingWFSLayer2 = (mIndex: string, filePath: string, layername: string, num: number) => {
	const baseUrl = BASE_CONFIG.sliceService;
	const source = new TileWMS({
		url: filePath, // WMS 服务的 URL
		params: {
			LAYERS: layername,
			TILED: true,
			FORMAT: "image/png",
		},
		serverType: "geoserver",
	});

	// 创建图层
	const layer = new TileLayer({
		source: source,
		zIndex: 2022, // 设置图层的层级
	});
	if (num == 1) {
		slicingLayerList1[layername] = layer;
	} else {
		slicingLayerList2[layername] = layer;
	}
	mapList[mIndex]?.addLayer(layer);
	console.log(slicingLayerList, "addslicingLayerList");
};
// 移除切片图层
const removeSlicingLayer = (mIndex: string, filePath: string) => {
	console.log(slicingLayerList[filePath], filePath, "removeSlicingLayer");

	if (slicingLayerList[filePath] !== undefined) {
		mapList[mIndex]?.removeLayer(slicingLayerList[filePath]);
		slicingLayerList[filePath] = undefined;
	}
};
// 移除所有切片图层
const removeAllSlicingLayer = (mIndex: string) => {
	console.log(slicingLayerList);

	for (const i in slicingLayerList) {
		if (slicingLayerList[i] !== undefined) {
			mapList[mIndex]?.removeLayer(slicingLayerList[i]);
			slicingLayerList[i] = undefined;
		}
	}
};
const removeAllLayersExceptBase = (mIndex: any) => {
	const view = mapList[mIndex]?.getView();
	const map = view.getMap();
	const layers = map.getLayers(); // 获取所有图层

	layers.forEach((layer: any) => {
		// 检查图层类型是否为 TileLayer（底图层通常是 TileLayer 或 ImageLayer）
		map.removeLayer(layer); // 移除非底图层
	});
};

const hasSlicingLayer = (mIndex: string, filePath: string) => {
	let has = false;
	if (slicingLayerList[filePath] !== undefined) {
		has = true;
	}
	return has;
};

/**--------------------------------切片图层相关--------------------------------------------*/

/**--------------------------------测量相关--------------------------------------------*/

/**
 * Currently drawn feature.
 * @type {import("../src/ol/Feature.js").default}
 */
let sketch: Feature | null;

/**
 * The help tooltip element.
 * @type {HTMLElement}
 */
let helpTooltipElement: HTMLElement | null = null;

/**
 * Overlay to show the help messages.
 * @type {Overlay}
 */
let helpTooltip: Overlay;

/**
 * The measure tooltip element.
 * @type {HTMLElement}
 */
let measureTooltipElement: HTMLElement | null = null;

/**
 * Overlay to show the measurement.
 * @type {Overlay}
 */
let measureTooltip: Overlay;
let drawingStatus = false;
/**
 * Message to show when the user is drawing a polygon.
 * @type {string}
 */
const continuePolygonMsg = "点击开始面积测量";

/**
 * Message to show when the user is drawing a line.
 * @type {string}
 */
const continueLineMsg = "点击开始距离测量";

/**
 * Handle pointer move.
 * @param {import("../src/ol/MapBrowserEvent").default} evt The event.
 */
const pointerMoveHandler = function (evt: any, helpMsg: string) {
	if (!helpTooltipElement) {
		return;
	}
	if (evt.dragging) {
		return;
	}
	/** @type {string} */
	// let helpMsg = "点击开始测量";
	if (sketch) {
		const geom = sketch.getGeometry();
		if (geom instanceof Polygon) {
			helpMsg = continuePolygonMsg;
		} else if (geom instanceof LineString) {
			helpMsg = continueLineMsg;
		}
	}

	helpTooltipElement.innerHTML = helpMsg;
	helpTooltip?.setPosition(evt.coordinate);
	if (drawingStatus) {
		helpTooltipElement.style.display = "block";
	} else {
		helpTooltipElement.style.display = "none";
	}
	helpTooltipElement.classList.remove("hidden");
};

const pointerMoveOutHandler = function () {
	if (!helpTooltipElement) {
		return;
	}
	helpTooltipElement.classList.add("hidden");
};

// 添加地图鼠标移动监听事件
const addMapPointerMove = (mIndex: string, helpMsg?: string) => {
	const msg = helpMsg || "点击开始测量";
	drawingStatus = true;
	mapList[mIndex]?.addEventListener("pointermove", (event) => pointerMoveHandler(event, msg));
	mapList[mIndex]?.getViewport().addEventListener("mouseout", pointerMoveOutHandler);
};

// 移除地图鼠标移动监听事件
const removeMapPointerMove = (mIndex: string, helpMsg?: string) => {
	const msg = helpMsg || "点击开始测量";
	mapList[mIndex]?.removeEventListener("pointermove", (event) => pointerMoveHandler(event, msg));
	mapList[mIndex]?.getViewport().removeEventListener("mouseout", pointerMoveOutHandler);
};

let draw: Draw; // global so we can remove it later
let overlayerList: any[] = [];

/**
 * Format length output.
 * @param {LineString} line The line.
 * @return {string} The formatted length.
 */
const formatLength = function (line: any, mIndex: string) {
	const mapProj = mapList[mIndex]?.getView().getProjection();
	const length = getLength(line, { projection: mapProj });
	let output: string;
	if (length > 100) {
		output = Math.round((length / 1000) * 100) / 100 + " " + "km";
	} else {
		output = Math.round(length * 100) / 100 + " " + "m";
	}
	return output;
};

/**
 * Format area output.
 * @param {Polygon} polygon The polygon.
 * @return {string} Formatted area.
 */
const formatArea = function (polygon: any, mIndex: string) {
	const mapProj = mapList[mIndex]?.getView().getProjection();
	const area = getArea(polygon, { projection: mapProj });
	let output: string;
	if (area > 10000) {
		output = Math.round((area / 1000000) * 100) / 100 + " " + "km<sup>2</sup>";
	} else {
		output = Math.round(area * 100) / 100 + " " + "m<sup>2</sup>";
	}
	return output;
};

/**
 *
 * @param {string} typeSelect - 测量类型，长度或面积
 * @param {Function | undefined} callBack - 回调函数，绘制完成后调用的函数
 */

function addMeasureInteraction(
	mIndex: string,
	typeSelect: string,
	callBack: Function | undefined = undefined
) {
	let geometry: any;
	const type = typeSelect === "area" ? "Polygon" : "LineString";
	draw = new Draw({
		source: measureVectorLayerList[mIndex]?.getSource() || new VectorSource(),
		type,
		style: new Style({
			fill: new Fill({
				color: "rgba(255, 255, 255, 0.2)",
			}),
			stroke: new Stroke({
				color: "rgba(255, 255, 0, 1)",
				lineDash: [10, 10],
				width: 2,
			}),
		}),
	});
	mapList[mIndex]?.addInteraction(draw);

	let listener: any;
	draw.on("drawstart", function (evt: any) {
		drawingStatus = false;
		// set sketch
		sketch = evt.feature;

		/** @type {import("../src/ol/coordinate.js").Coordinate|undefined} */
		let tooltipCoord = evt.coordinate;
		listener = sketch?.getGeometry()?.on("change", function (evt) {
			const geom = evt.target;
			geometry = geom;
			let output = "";
			if (geom instanceof Polygon) {
				output = formatArea(geom, mIndex);
				tooltipCoord = geom.getInteriorPoint().getCoordinates();
			} else if (geom instanceof LineString) {
				output = formatLength(geom, mIndex);
				tooltipCoord = geom.getLastCoordinate();
			}
			measureTooltipElement!.innerHTML = output || "";
			measureTooltip.setPosition(tooltipCoord);
		});
	});

	draw.on("drawend", function () {
		measureTooltipElement!.className = "ol-tooltip ol-tooltip-static";
		measureTooltip.setOffset([0, -7]);
		// unset sketch
		sketch = null;
		// unset tooltip so that a new one can be created
		measureTooltipElement = null;
		createMeasureTooltip(mIndex);
		unByKey(listener);
		if (callBack !== undefined) {
			callBack(geometry);
		}
	});
}

/**
 * Creates a new help tooltip
 */
function createHelpTooltip(mIndex: string) {
	if (helpTooltipElement) {
		helpTooltipElement!.parentNode!.removeChild(helpTooltipElement);
	}
	helpTooltipElement = document.createElement("div");
	helpTooltipElement.className = "ol-tooltip hidden";
	helpTooltip = new Overlay({
		element: helpTooltipElement,
		offset: [15, 0],
		positioning: "center-left",
	});
	mapList[mIndex]?.addOverlay(helpTooltip);
	overlayerList.push(helpTooltip);
}

/**
 * Creates a new measure tooltip
 */
function createMeasureTooltip(mIndex: string) {
	if (measureTooltipElement) {
		measureTooltipElement.parentNode!.removeChild(measureTooltipElement);
	}
	measureTooltipElement = document.createElement("div");
	measureTooltipElement.className = "ol-tooltip ol-tooltip-measure";
	measureTooltip = new Overlay({
		element: measureTooltipElement,
		offset: [0, -15],
		positioning: "bottom-center",
		stopEvent: false,
		insertFirst: false,
	});
	mapList[mIndex]?.addOverlay(measureTooltip);
	overlayerList.push(measureTooltip);
}

// 移除绘制测量范围交互行为
const removeMeasureDrawInteraction = (mIndex: string) => {
	mapList[mIndex]?.removeInteraction(draw);
};

// 清楚测量结果
const clearMeasureResult = (mIndex: string) => {
	measureVectorLayerList[mIndex]?.getSource()?.clear();
	overlayerList.forEach((overlayer) => {
		mapList[mIndex]?.removeOverlay(overlayer);
	});
	overlayerList = [];
};

// 移除提示信息
const removeAllTooltip = () => {
	if (helpTooltipElement) {
		helpTooltipElement!.parentNode!.removeChild(helpTooltipElement);
		helpTooltipElement = null;
	}
	if (measureTooltipElement) {
		measureTooltipElement.parentNode!.removeChild(measureTooltipElement);
		measureTooltipElement = null;
	}
};

/**--------------------------------测量相关--------------------------------------------*/

export default {
	// 地图实例列表
	mapList,
	// 矢量图层列表
	vectorLayerList,
	// 地图初始化
	initMap,
	// 几何转换为wkt
	geometryToWkt,
	// feature转wkt
	featureToWkt,
	// feature转GeoJson
	featureToGeoJson,
	// GeoJson转feature
	geoJsonToFeature,
	// 要素清除
	clearVectorLayer,
	// 通过wkt加载要素
	loadFeatureByWkt,
	// 矢量图层添加要素
	addFeatureToVector,
	// 根据wkt定位范围
	locationByWkt,
	locationByBbox,
	/**--------------------------------Draw交互行为相关--------------------------------------------*/
	// 添加绘制交互行为
	addDrawInteraction,
	// 移除绘制交互行为
	removeDrawInteraction,
	/**--------------------------------Draw交互行为相关--------------------------------------------*/
	/**--------------------------------Select交互行为相关--------------------------------------------*/
	// 添加选中交互行为
	addSelectInteraction,
	// 移除选中交互行为
	removeSelectInteraction,
	// 切换要素选中状态
	changeFeatureStatus,
	/**--------------------------------Select交互行为相关--------------------------------------------*/
	/**--------------------------------Modify交互行为相关--------------------------------------------*/
	// 添加要素编辑行为
	addModifyInteraction,
	removeModifyInteraction,
	// 移除要素编辑行为
	/**--------------------------------Modify交互行为相关--------------------------------------------*/
	/**--------------------------------切片图层相关--------------------------------------------*/
	// 调切片服务，添加图层
	addSlicingLayer,
	addSlicingWFSLayer,
	// 移除切片图层
	removeSlicingLayer,
	// 移除所有切片图层
	removeAllSlicingLayer,
	// 判断切片图层是否存在
	hasSlicingLayer,
	addjsonFeature,
	/**--------------------------------切片图层相关--------------------------------------------*/
	/**--------------------------------测量相关--------------------------------------------*/
	// 添加地图鼠标移动监听事件
	addMapPointerMove,
	// 移除地图鼠标移动监听事件
	removeMapPointerMove,
	// 添加绘制测量范围交互行为
	addMeasureInteraction,
	// 移除绘制测量范围交互行为
	removeMeasureDrawInteraction,
	// 添加鼠标帮助提示
	createHelpTooltip,
	// 添加鼠标测量提示
	createMeasureTooltip,
	// 清楚测量结果
	clearMeasureResult,
	// 移除提示信息
	removeAllTooltip,
	//根据id删除
	removeFeatureById,
	removeAllLayersExceptBase,
	addSlicingWFSLayer2,
	/**--------------------------------测量相关--------------------------------------------*/
};
